/**
 *
 */
package org.suren.littlebird.views;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.part.ViewPart;
import org.suren.littlebird.actions.Reload;
import org.suren.littlebird.actions.bundle.SuRenBundleInstallAction;
import org.suren.littlebird.actions.bundle.SuRenBundlePreferenceAction;
import org.suren.littlebird.actions.bundle.SuRenBundleReload;
import org.suren.littlebird.actions.bundle.SuRenBundleReloadAction;
import org.suren.littlebird.actions.bundle.SuRenBundleStartAction;
import org.suren.littlebird.actions.bundle.SuRenBundleStopAction;
import org.suren.littlebird.actions.bundle.SuRenBundleUninstallAction;
import org.suren.littlebird.actions.bundle.SuRenBundleUpdateAction;
import org.suren.littlebird.editors.BundleEditorInput;
import org.suren.littlebird.editors.BundleStorage;
import org.suren.littlebird.layout.BorderData;
import org.suren.littlebird.layout.BorderLayout;
import org.suren.littlebird.po.SuRenBundle;
import org.suren.littlebird.server.BundleServer;
import org.suren.littlebird.server.BundleServerFactory;
import org.suren.littlebird.views.drop.BundleDropTarget;
import org.suren.littlebird.views.filter.SuRenBundleViewerFilter;
import org.suren.littlebird.views.listener.SorterAdapter;
import org.suren.littlebird.views.provider.SuRenBundleFieldProvider;
import org.suren.littlebird.views.provider.SuRenBundleProvider;
import org.suren.littlebird.views.sorter.DefaultViewerSorter;

/**
 * @author suren
 * @author fy911
 * bundle的管理（启动、停止、安装、卸载）
 */
public class SuRenBundleView extends ViewPart
{
	private TableViewer	viewer;
	private Table	table;

	private Label statusLabel;

	private InstallBundleDialog dialog;
	private Reload bundleReload;

	private SuRenBundleInstallAction installAction;
	private SuRenBundleStopAction stopAction;
	private SuRenBundleStartAction startAction;
	private SuRenBundleUninstallAction uninstallAction;
	private SuRenBundleUpdateAction updateAction;

	@Override
	public void createPartControl(Composite parent)
	{
		parent.setLayout(new BorderLayout());

		final SuRenBundleViewerFilter filter = new SuRenBundleViewerFilter();

 		viewer = new TableViewer(parent, SWT.MULTI  | SWT.V_SCROLL | SWT.H_SCROLL| SWT.FULL_SELECTION | SWT.BORDER);
		viewer.setContentProvider(new SuRenBundleProvider());
		viewer.setLabelProvider(new SuRenBundleFieldProvider());
		viewer.addFilter(filter);
		viewer.addSelectionChangedListener(viewerSelectionChange);

		table = viewer.getTable();
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		
		table.addMouseListener(tableMouseListener);

		TableLayout tableColLayout = new TableLayout();
		table.setLayout(tableColLayout);

		tableColLayout.addColumnData(new ColumnWeightData(1, true));
		TableColumn idCol = new TableColumn(table, SWT.None);
		idCol.setText("Id");
		idCol.addSelectionListener(new SelectionAdapter(){
            boolean asc = true;
            public void widgetSelected(SelectionEvent e){
            	viewer.setSorter(asc?DefaultViewerSorter.ID_ASC:DefaultViewerSorter.ID_DESC);
             	asc = !asc;
            }
        });

		tableColLayout.addColumnData(new ColumnWeightData(7, true));
		TableColumn nameCol = new TableColumn(table, SWT.None);
		nameCol.setText("Name");
		nameCol.addSelectionListener(new SelectionAdapter(){
            boolean asc = true;
            public void widgetSelected(SelectionEvent e){
            	viewer.setSorter(asc?DefaultViewerSorter.NAME_ASC:DefaultViewerSorter.NAME_DESC);
             	asc = !asc;
            }
        });
		tableColLayout.addColumnData(new ColumnWeightData(1, true));
		TableColumn versionCol = new TableColumn(table, SWT.None);
		versionCol.setText("Version");
		versionCol.addSelectionListener(new SelectionAdapter(){
            boolean asc = true;
            public void widgetSelected(SelectionEvent e){
            	viewer.setSorter(asc?DefaultViewerSorter.VERSION_ASC:DefaultViewerSorter.VERSION_DESC);
             	asc = !asc;
            }
        });
		tableColLayout.addColumnData(new ColumnWeightData(1, true));
		TableColumn stateCol = new TableColumn(table, SWT.None);
		stateCol.setText("State");
		stateCol.addSelectionListener(new SelectionAdapter(){
            boolean asc = true;
            public void widgetSelected(SelectionEvent e){
            	viewer.setSorter(asc?DefaultViewerSorter.STATUS_ASC:DefaultViewerSorter.STATUS_DESC);
             	asc = !asc;
            }
        });
		dialog = new InstallBundleDialog(parent.getShell());

		Composite statusAndSearch = new Composite(parent, SWT.SEARCH);
		statusAndSearch.setLayoutData(BorderData.NORTH);
		statusAndSearch.setLayout(new BorderLayout());

		statusLabel = new Label(statusAndSearch, SWT.None);
		statusLabel.setLayoutData(BorderData.NORTH);

		final Text text = new Text(statusAndSearch, SWT.SINGLE | SWT.BORDER | SWT.SEARCH
                | SWT.ICON_CANCEL);
		text.setSize(30, 10);
		text.setLayoutData(BorderData.SOUTH);
		text.setToolTipText("Type The Filter Text");
		text.setMessage("Filter");
  		text.addListener(SWT.CHANGED, new Listener()
		{

			@Override
			public void handleEvent(Event event)
			{
				filter.setName(text.getText());
				viewer.refresh();
 			}
		});

		bundleReload = new SuRenBundleReload(viewer,
				getViewSite().getActionBars().getStatusLineManager(), statusLabel);

		createActions();

		createToolBar();

		createContextMenu();

		createDragSource();
		
		//挂载扩展点
		regExtension();
	}
	
	private MouseListener tableMouseListener = new MouseAdapter() {

		@Override
		public void mouseDoubleClick(MouseEvent e) {
			Object source = e.getSource();
			TableItem item = table.getItem(new org.eclipse.swt.graphics.Point(e.x, e.y));
			BundleServer bundleServer = BundleServerFactory.getInstance();
			
			long id = Long.parseLong(item.getText());
			SuRenBundle bundle = bundleServer.getById(id);
			if(bundle != null)
			{
				IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				try {
					BundleEditorInput input = new BundleEditorInput();
					input.setBundleStorage(new BundleStorage(bundle));
					window.getActivePage().openEditor(input, "org.suren.littlebird.editors.BundleEditor");
				} catch (PartInitException ex) {
					ex.printStackTrace();
				}
			}
		}
	};
	
	@SuppressWarnings("restriction")
	private void regExtension()
	{
		IExtensionRegistry reg = Platform.getExtensionRegistry();
		IConfigurationElement[] extensions = reg.getConfigurationElementsFor("org.suren.littlebird.bundles.list");
		if(extensions != null)
		{
			for(IConfigurationElement ele : extensions)
			{
				if("column".equals(ele.getName()))
				{
					String textAttr = ele.getAttribute("text");
					String sorterCls = ele.getAttribute("sorter");
					TableColumn col = new TableColumn(table, SWT.None);
					col.setText(textAttr);
					
					try {
						SorterAdapter ext = (SorterAdapter) WorkbenchPlugin.createExtension(ele, "sorter");
						ext.setViewer(viewer);
						col.addSelectionListener(ext);
					} catch (CoreException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	private void createToolBar()
	{
		IActionBars actionBars = getViewSite().getActionBars();
		actionBars.updateActionBars();
		actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),null);

		IToolBarManager toolBarMgr = actionBars.getToolBarManager();

		toolBarMgr.add(new SuRenBundleReloadAction(bundleReload));
		toolBarMgr.add(updateAction);
		toolBarMgr.add(new Separator());
		toolBarMgr.add(startAction);
		toolBarMgr.add(stopAction);
		toolBarMgr.add(new Separator());
		toolBarMgr.add(installAction);
		toolBarMgr.add(uninstallAction);

		IMenuManager menuMgr = getViewSite().getActionBars().getMenuManager();

		menuMgr.add(new SuRenBundlePreferenceAction(getViewSite().getShell()));
	}

	private void createContextMenu()
	{
	}

	/**
	 *
	 */
	private void createDragSource()
	{
		DropTarget 	dropTarget = new DropTarget(table, DND.DROP_COPY
				| DND.DROP_LINK  | DND.DROP_MOVE | DND.DROP_TARGET_MOVE);

		dropTarget.setTransfer(new Transfer[]{
				LocalSelectionTransfer.getTransfer(),
				FileTransfer.getInstance()
		});
		dropTarget.addDropListener(new BundleDropTarget(dialog){

			@Override
			protected void callBack(boolean scpResult, String dstFile)
			{
				List<String>	pathList = new ArrayList<String>();
				pathList.add(dstFile);

				installAction.setPathList(pathList);
				installAction.run();
			}
		});
	}

	private void createActions()
	{
		installAction = new SuRenBundleInstallAction(viewer, dialog, bundleReload);
		startAction = new SuRenBundleStartAction(table, bundleReload);
		stopAction = new SuRenBundleStopAction(table, bundleReload);
		updateAction = new SuRenBundleUpdateAction(table, bundleReload);
		uninstallAction = new SuRenBundleUninstallAction(table, bundleReload);

		startAction.setEnabled(false);
		stopAction.setEnabled(false);
		updateAction.setEnabled(false);
		uninstallAction.setEnabled(false);
	}

	@Override
	public void setFocus()
	{
		viewer.getControl().setFocus();
	}

	private ISelectionChangedListener viewerSelectionChange = new ISelectionChangedListener()
	{

		@Override
		public void selectionChanged(SelectionChangedEvent event)
		{
			boolean enabled = !event.getSelection().isEmpty();

			startAction.setEnabled(enabled);
			stopAction.setEnabled(enabled);
			updateAction.setEnabled(enabled);
			uninstallAction.setEnabled(enabled);
		}
	};
}
